<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  xmlns:c="livcos.org/ns/cosmos"
  xmlns:da="livcos.org/ns/cosmos/data-access"
  xmlns:cb="livcos.org/ns/clipboard"
  xmlns:u="livcos.org/ns/cosmos/update"
  xmlns:t="livcos.org/ns/cosmos/type"
  xmlns:f="livcos.org/ns/xslt/function"
  xmlns:job="livcos.org/ns/process/job"
  exclude-result-prefixes="c cb t da f">

	<xsl:import href="../Edit.xsl" />
	
  <xsl:param name="entryId"/>
	
  <xsl:variable name="sessionObjId" select="$jobObject/c:request/@session"/>
	<xsl:variable name="session" select="document(concat($sessionObjId, '.cosmos'))/*"/>
  <xsl:variable name="clipboard" select="$session/cb:clipboard"/>
  <xsl:variable name="entry" as="element()?"
    select="if (normalize-space($entryId) != '') then $clipboard/*[@id = $entryId] else $clipboard/cb:entry[last()]"/>
  
  <xsl:template match="/">
    <xsl:apply-templates select="$jobObject/c:request/parameter/*" />
  	<job:feed ref="/livcos.org/web/editor/EditResponse" stream="response" base="job">
  		<job:param name="view" value="{$view}"/>
  	</job:feed>
  </xsl:template>
  
  <xsl:template match="*">
  </xsl:template>
  
  <xsl:template match="pasteInto">
    <u:context ref="{$objId}" scope="{$scope}">
      <u:context select="{$idPath}">
        <u:context select="{$path}">
          <xsl:apply-templates select="../*[starts-with(name(.),'ns')]" mode="ns"/>
          <xsl:apply-templates select="$entry" mode="info"/>
          <xsl:apply-templates select="$entry/node()" mode="paste">
            <xsl:with-param name="into" select="true()"/>
          </xsl:apply-templates>
        </u:context>
      </u:context>
    </u:context>
  	<job:transform def="{$integrityCheckObjId}">
      <job:param name="obj" value="{$objId}"/>
    </job:transform>
  </xsl:template>
  
  <xsl:template match="paste">
    <u:context ref="{$objId}" scope="{$scope}">
      <u:context select="{$idPath}">
        <xsl:apply-templates select="$entry" mode="info"/>
        <xsl:apply-templates select="$entry/node()" mode="paste"/>
      </u:context>
    </u:context>
  	<job:transform def="{$integrityCheckObjId}">
      <job:param name="obj" value="{$objId}"/>
    </job:transform>
  </xsl:template>
  
  <xsl:template match="cb:entry[@type = 'cut']" mode="info">
    <u:info>
      <move>
        <xsl:copy-of select="@entity | @parent | @index | @node | @object"/>
      </move>
    </u:info>
  </xsl:template>
  
  <xsl:template match="cb:entry[@type = 'copy']" mode="info">
    <u:info>
      <copy>
        <xsl:copy-of select="@entity | @parent | @index | @node | @object"/>
      </copy>
    </u:info>
  </xsl:template>
  
	<xsl:template match="node()" mode="paste">
		<xsl:param name="into"/>
		<u:insert select=".">
			<xsl:if test="not($into)">
				<xsl:attribute name="position">before</xsl:attribute>
			</xsl:if>
			<xsl:copy-of select="." copy-namespaces="no"/>
		</u:insert>
	</xsl:template>
	
	<xsl:template match="*[@id]" mode="paste">
		<xsl:param name="into"/>
		<u:insert select=".">
			<xsl:if test="not($into)">
				<xsl:attribute name="position">before</xsl:attribute>
			</xsl:if>
			<xsl:copy copy-namespaces="no">
				<xsl:copy-of select="@*" copy-namespaces="no"/>
				<xsl:attribute name="{../@type}-src">
					<xsl:if test="../@object != $objId">
						<xsl:value-of select="../@object"/>
					</xsl:if>
					<xsl:text>#</xsl:text>
					<xsl:value-of select="@id"/>
				</xsl:attribute>
				<xsl:copy-of select="node()" copy-namespaces="no"/>
			</xsl:copy>
		</u:insert>
	</xsl:template>
	
	<xsl:template match="t:attribute" mode="paste">
    <u:insert select=".">
      <u:attribute name="{@name}"><xsl:value-of select="."/></u:attribute>
    </u:insert>
  </xsl:template>
  
  <xsl:template match="t:namespace" mode="paste">
    <u:decl-namespace select="." prefix="{@prefix}"><xsl:value-of select="."/></u:decl-namespace>
  </xsl:template>
  
  <xsl:template name="createEntry">
    <xsl:param name="type"/>
  	<xsl:call-template name="build"/>
  	<u:context ref="{$sessionObjId}" scope="meta">
      <u:insert select="cb:clipboard">
      	<u:namespace prefix="cb" uri="livcos.org/ns/clipboard" />
      	<!-- TODO 6: proper entry ID (entity ID are not managed for the Clipboard object ({new-id()} won't work)) -->
        <cb:entry id="entry_{count($clipboard/cb:entry) + 1}" type="{$type}" object="{$objId}"
          time="{current-dateTime()}">
          <xsl:choose>
            <xsl:when test="matches($id,'^[0-9]+')">
              <xsl:attribute name="node">
                <xsl:value-of select="$id"/>
              </xsl:attribute>
              <xsl:copy-of select="f:nodeById($id, document(concat($objId,'.content')))"/>
            </xsl:when>
            <xsl:when test="normalize-space($id) != ''">
              <xsl:attribute name="entity">
                <xsl:value-of select="$id"/>
              </xsl:attribute>
              <xsl:variable name="entity" select="document(concat($objId,'.content'))/*//*[@id = $id]"/>
              <xsl:attribute name="parent">
                <xsl:value-of select="f:nodeId($entity/..)"/>
              </xsl:attribute>
              <xsl:attribute name="index">
                <xsl:value-of select="f:childIndex($entity)"/>
              </xsl:attribute>
              <xsl:copy-of select="$entity"/>
            </xsl:when>
            <xsl:otherwise>
              <xsl:element name="{replace($objId,'.*/','')}" namespace="livcos.org/ns/cosmos">
                <xsl:copy-of select="document(concat($objId,'.content'))/*"/>
              </xsl:element>
            </xsl:otherwise>
          </xsl:choose>
        </cb:entry>
      </u:insert>
    </u:context>
  </xsl:template>
  
  <xsl:template match="copy">
    <xsl:call-template name="createEntry">
      <xsl:with-param name="type" select="'copy'"/>
    </xsl:call-template>
  </xsl:template>
  
  <xsl:template match="cut">
    <xsl:call-template name="createEntry">
      <xsl:with-param name="type" select="'cut'"/>
    </xsl:call-template>
    <u:context ref="{$objId}" scope="{$scope}">
      <xsl:choose>
        <xsl:when test="contains($id, '@xmlns')">
          <u:decl-namespace select="{$idPath}" prefix="{substring-after($id,'@xmlns:')}" uri=""/>
        </xsl:when>
        <xsl:when test="matches($id,'^[0-9]+')">
          <u:delete select="{$idPath}"/>
        </xsl:when>
        <xsl:otherwise>
          <u:delete select="*//*[@id = '{$id}']"/>
        </xsl:otherwise>
      </xsl:choose>
    </u:context>
  </xsl:template>
  
  <xsl:template match="node()" mode="applyNode">
    <xsl:apply-templates select="." mode="copy"/>
  </xsl:template>
  
  <xsl:template match="@*" mode="applyNode">
    <t:attribute name="{name()}"><xsl:value-of select="."/></t:attribute>
  </xsl:template>
  
  <xsl:template match="@*|node()" mode="copy">
    <xsl:copy>
      <xsl:apply-templates select="@*|node()" mode="copy"/>
    </xsl:copy>
  </xsl:template>
  
  <xsl:template match="@id" mode="copy">
    <xsl:attribute name="id">{{new-id()}}</xsl:attribute>
  </xsl:template>
  
  <xsl:template match="remove">
    <u:context ref="{$sessionObjId}" scope="meta">
      <u:delete select="cb:clipboard/cb:entry[@id = '{$entryId}']">
        <u:namespace prefix="cb" uri="livcos.org/ns/clipboard" />
      </u:delete>
    </u:context>
  </xsl:template>
  
  <xsl:template match="clear">
  	<u:context ref="{$sessionObjId}" scope="meta">
  		<u:delete select="cb:clipboard/cb:entry">
        <u:namespace prefix="cb" uri="livcos.org/ns/clipboard" />
      </u:delete>
    </u:context>
  </xsl:template>
  
	<xsl:template match="build">
		<xsl:call-template name="build"/>
	</xsl:template>
	
	<xsl:template name="build">
		<xsl:if test="not($clipboard)">
			<u:context ref="{$sessionObjId}" scope="meta">
				<u:insert select=".">
					<cb:clipboard/>
				</u:insert>
			</u:context>
		</xsl:if>
	</xsl:template>
	
</xsl:stylesheet>
